/*
 * Copyright 2002-2014 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.beans.factory;

/**
 * Callback interface triggered at the end of the singleton pre-instantiation phase
 * during {@link BeanFactory} bootstrap. This interface can be implemented by
 * singleton beans in order to perform some initialization after the regular
 * singleton instantiation algorithm, avoiding side effects with accidental early
 * initialization (e.g. from {@link ListableBeanFactory#getBeansOfType} calls).
 * In that sense, it is an alternative to {@link InitializingBean} which gets
 * triggered right at the end of a bean's local construction phase.
 *
 * <p>This callback variant is somewhat similar to
 * {@link org.springframework.context.event.ContextRefreshedEvent} but doesn't
 * require an implementation of {@link org.springframework.context.ApplicationListener},
 * with no need to filter context references across a context hierarchy etc.
 * It also implies a more minimal dependency on just the {@code beans} package
 * and is being honored by standalone {@link ListableBeanFactory} implementations,
 * not just in an {@link org.springframework.context.ApplicationContext} environment.
 *
 * <p><b>NOTE:</b> If you intend to start/manage asynchronous tasks, preferably
 * implement {@link org.springframework.context.Lifecycle} instead which offers
 * a richer model for runtime management and allows for phased startup/shutdown.
 *
 * @author Juergen Hoeller
 * @since 4.1
 * @see org.springframework.beans.factory.config.ConfigurableListableBeanFactory#preInstantiateSingletons()
 */
/*
 * 此接口定义了一个回调方法，该方法在BeanFactory启动时，Singleton对象预实例化阶段结束时被触发。这为Singleton Bean提供了一个
 * 在常规Singleton实例化算法之后执行某些初始化的时机，避免了因意外的早期初始化（例如，通过ListableBeanFactory的getBeansOfType调用）
 * 而产生的副作用。与InitializingBean接口不同，InitializingBean在Bean构造过程的末尾立即触发。
 *
 * 该回调方法与org.springframework.context.event.ContextRefreshedEvent有些相似，但不需要实现org.springframework.context.ApplicationListener，
 * 无需在上下文层次结构中过滤上下文引用等。而且，这仅依赖于beans包，且不仅在ApplicationContext环境下受到尊重，也适用于独立的ListableBeanFactory实现。
 *
 * 如果打算启动/管理异步任务，最好实现org.springframework.context.Lifecycle，因为它提供了更丰富的运行时管理模型，并允许分阶段启动/关闭。
 *
 * @author Juergen Hoeller
 * @since 4.1
 * @see org.springframework.beans.factory.config.ConfigurableListableBeanFactory#preInstantiateSingletons()
 */
public interface SmartInitializingSingleton {

    /**
     * 在Singleton预实例化阶段结束时调用，保证所有常规Singleton Bean已经被创建。
     * 在此方法内调用ListableBeanFactory的getBeansOfType不会在启动过程中引发意外的副作用。
     * <p>注意：此回调不会触发在需求时懒加载的Singleton Bean，也不会触发其他任何Bean作用域的Bean。
     * 请谨慎使用，仅适用于具有预期启动语义的Bean。
     */
    void afterSingletonsInstantiated();

}
